{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "Pytorch入门实战（1） - 实现线性回归"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "# 涉及知识点\n",
    "[Pytorch nn.Module的基本使用](https://blog.csdn.net/zhaohongfei_358/article/details/122797244)\n",
    "\n",
    "[Pytorch nn.Linear的基本用法](https://blog.csdn.net/zhaohongfei_358/article/details/122797190)"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 将线性回归神经网络化\n",
    "\n",
    "线性回归也可以看作一个简单的神经网络。以一个特征的一元线性回归为例：\n",
    "\n",
    "$$\n",
    "y = w \\cdot x + b\n",
    "$$\n",
    "\n",
    "可以改造下图神经网络：\n",
    "\n",
    "<img src=\"./asserts/images/01_01.png\" width=\"300\">\n",
    "\n",
    "若将x泛化为向量，即 $x=(x_1, x_2, ... , x_n)$，则对应神经网络为：\n",
    "\n",
    "<img src=\"./asserts/images/01_02.png\" width=\"300\">"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "# Pytorch 代码实现\n",
    "\n",
    "## 一元线性回归Pytorch方式实现"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [],
   "source": [
    "import torch\n",
    "import matplotlib.pyplot as plt"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "首先生成测试数据："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([[7.2543],\n        [0.8824],\n        [8.1629]])"
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = torch.rand(100, 1) * 10  # 生成一个100行一列的数据；该数据服从[0,10]的uniform分布\n",
    "X[:3]"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "data": {
      "text/plain": "tensor([[33.6710],\n        [13.3356],\n        [36.9041]])"
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = 3 * X + 10 + torch.randn(100, 1) * 3 # 计算其对应的y值；y也是100行1列的\n",
    "y[:3]"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "将生成的数据绘制成散点图，看下效果："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X.numpy(), y.numpy())\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "接下来定义线性回归预训练模型："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [],
   "source": [
    "class LinearRegression(torch.nn.Module):\n",
    "    \"\"\"\n",
    "    模型需要继承 `torch.nn.Module`，在Pytorch中，模型都需要继承该类\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(self):\n",
    "        super().__init__()  # 初始化Module类\n",
    "\n",
    "        \"\"\"\n",
    "        定义我们神经网络的第一层（线性层）。其接受的重要三个参数：\n",
    "        in_features: 输入神经元的个数\n",
    "        out_features：输出神经元的个数\n",
    "        bias：是否包含偏置\n",
    "\n",
    "\t\t更多，关于torch.nn.Linear，可以参考：https://pytorch.org/docs/stable/nn.html#linear-layers\n",
    "        \"\"\"\n",
    "        self.linear = torch.nn.Linear(in_features=1, out_features=1, bias=True)\n",
    "\n",
    "    def forward(self, x):\n",
    "        \"\"\"\n",
    "        前向传播计算神经网络的输出\n",
    "        \"\"\"\n",
    "        predict = self.linear(x)\n",
    "        return predict"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "到这里预训练模型已经构建完毕。初始化预训练模型："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [],
   "source": [
    "model = LinearRegression() # 初始化模型"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "定义梯度下降器，这里选择随机梯度下降法："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parameter containing:\n",
      "tensor([[-0.7801]], requires_grad=True)\n",
      "Parameter containing:\n",
      "tensor([0.3026], requires_grad=True)\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "torch.optim.SGD 接受几个重要的参数：\n",
    "- params: 模型参数\n",
    "- lr: 学习率\n",
    "\"\"\"\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)\n",
    "\n",
    "# 这里可以看下模型参数\n",
    "for param in model.parameters(): # 因为模型有多个参数，所以model.parameters会返回一个可迭代的对象\n",
    "    print(param)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "定义损失函数，这里使用MSE："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [],
   "source": [
    "loss_function = torch.nn.MSELoss()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "此时就可以训练模型了："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [],
   "source": [
    "for epoch in range(10000): # 训练10000次\n",
    "    \"\"\"\n",
    "    1. 将X带入模型，其会自动调用前向传递，计算出每个x对应的y值\n",
    "    X.shape 和 predict_y.shape 都为(100,1),\n",
    "    \"\"\"\n",
    "    predict_y = model(X)\n",
    "\n",
    "    \"\"\"\n",
    "    2. 通过损失函数计算损失\n",
    "    \"\"\"\n",
    "    loss = loss_function(predict_y, y)\n",
    "\n",
    "    \"\"\"\n",
    "    3. 进行反向传播\n",
    "    \"\"\"\n",
    "    loss.backward()\n",
    "\n",
    "    \"\"\"\n",
    "    4. 更新权重\n",
    "    \"\"\"\n",
    "    optimizer.step()\n",
    "\n",
    "    \"\"\"\n",
    "    5.清空optimizer的梯度，否则会影响下次迭代\n",
    "    \"\"\"\n",
    "    optimizer.zero_grad()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "看下最后的参数，结果符合预期："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parameter containing:\n",
      "tensor([[3.0832]], requires_grad=True)\n",
      "Parameter containing:\n",
      "tensor([9.7287], requires_grad=True)\n"
     ]
    }
   ],
   "source": [
    "for param in model.parameters(): # 因为模型有多个参数，所以model.parameters会返回一个可迭代的对象\n",
    "    print(param)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "再重新绘制一下图，看下最终效果："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X, y)\n",
    "plt.plot(X, model(X).detach().numpy(), color='red')\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}